package io.bluerain.aclient.core;

import io.bluerain.aclient.attach.IndieCookie;
import io.bluerain.aclient.attach.IndieParam;
import io.bluerain.aclient.entities.Auth;
import io.bluerain.core.Obj;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wscl on 2015/6/10.
 */
public class BaseClient {

    private String url = null;
    private IndieCookie cookie = null;
    private IndieParam param = null;
    private String userAgent = null;
    private Auth auth;
    Invocation.Builder request = null;
    private String method;
    private List<String> languages = new ArrayList<>();

    /**
     * 实例化方法
     *
     * @return Client实例
     */
    public static BaseClient builder() {
        return new BaseClient();
    }

    public Response request() {
        return request(null);
    }

    public Response request(String httpMethod) {
        if (url == null)
            System.out.println("url为空异常。");
        //实例化request对象
        if (httpMethod == null) {
            httpMethod = this.method;
        }
        instanceHttpClient(httpMethod);
        if (cookie != null) {
            //放置cookie
            if (cookie != null) {
                List<Cookie> cookies = cookie.getCookies();
                if (cookies != null && cookies.size() > 0) {
                    for (Cookie c : cookies) {
                        request.cookie(c);
                    }
                }
            }
        }
        //设置UA
        if (userAgent != null)
            request.header("User-Agent", userAgent);
        //设置语言
        if (languages.size() > 0) {
            StringBuilder sbLan = new StringBuilder();
            for (String l : this.languages) {
                sbLan.append(l + ";");
            }
            request.header("Accept-Language", sbLan.toString());
        }
        //设置Auth
        if (auth != null)
            request.header("Authorization", getBasicAuthentication());
        javax.ws.rs.core.Response response = null;
        switch (httpMethod) {
            case HttpMethod.GET:
                response = request.get();
                break;
            case HttpMethod.POST:
                if (this.param != null) {
                    if (param.getEntity() != null) {

                        response = request.post(Entity.entity(param.getEntity(), MediaType.APPLICATION_JSON + ClientConstant.Content_Type_CharSet));
                    } else
                        response = request.post(Entity.form(param.toForm()));
                } else
                    response = request.post(Entity.form(new Form()));

                break;
        }
        return new Response(response);
    }

    private void instanceHttpClient(String httpMethod) {
        ResteasyClient client = build(); //client对象
        ResteasyWebTarget target = null; //目标对象
        switch (httpMethod) {
            case HttpMethod.GET:
                target = webTarget(client, this.url + (param != null ? param.toString() : ""));
                break;
            case HttpMethod.POST:
                target = webTarget(client, this.url);
                break;
        }
        request = target.request();
    }

    public BaseClient url(String url) {
        this.url = url;
        return this;

    }

    public BaseClient cookie(IndieCookie cookie) {
        this.cookie = cookie;
        return this;
    }

    public BaseClient param(IndieParam param) {
        this.param = param;
        return this;
    }

    public BaseClient userAgent(String userAgent) {
        this.userAgent = userAgent;
        return this;
    }

    public BaseClient auth(Auth auth) {
        this.auth = auth;
        return this;
    }

    public BaseClient language(String language, String... languages) {
        this.languages.add(language);
        if (Obj.notNullOrEmpty(languages)) {
            for (String l : languages) {
                this.languages.add(l);
            }
        }
        return this;
    }

    public BaseClient method(String method) {
        this.method = method;
        return this;
    }

    public static ResteasyClient build() {
        return new ResteasyClientBuilder().build();
    }

    public static void close(ResteasyClient client) {
        if (client != null)
            client.close();
    }

    public static ResteasyWebTarget webTarget(ResteasyClient client, String link) {
        return client.target(link);
    }

    private String getBasicAuthentication() {
        String token = this.auth.getUsername() + ":" + this.auth.getPassword();
        try {
            return "Basic " +
                    DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ex) {
            throw new IllegalStateException("Cannot encode with UTF-8", ex);
        }
    }
}
